#!/usr/bin/env python3
# run_type_checks.py
"""
MicroPython 协作开发指南 - 类型检查运行脚本
MicroPython Collaborative Development Guide - Type Checking Runner Script

自动运行所有类型检查工具
Automatically runs all type checking tools
"""

import subprocess
import sys
import os
from pathlib import Path
from typing import List, Tuple, Optional


def run_command(command: List[str], description: str) -> Tuple[bool, str, str]:
    """
    运行命令并返回结果 | Run command and return results
    
    参数 Parameters:
    - command (List[str]): 要执行的命令 | Command to execute
    - description (str): 命令描述 | Command description
    
    返回值 Returns:
    - Tuple[bool, str, str]: 成功标志、标准输出、错误输出 | Success flag, stdout, stderr
    """
    try:
        print(f"🔍 {description}")
        print(f"   命令 | Command: {' '.join(command)}")
        
        result = subprocess.run(
            command,
            capture_output=True,
            text=True,
            timeout=60,
            cwd=Path(__file__).parent
        )
        
        success = result.returncode == 0
        status_icon = "✅" if success else "❌"
        
        print(f"   {status_icon} {'成功' if success else '失败'} | {'Success' if success else 'Failed'}")
        
        if result.stdout.strip():
            print(f"   标准输出 | Stdout:\n{result.stdout}")
        
        if result.stderr.strip():
            print(f"   错误输出 | Stderr:\n{result.stderr}")
        
        return success, result.stdout, result.stderr
        
    except subprocess.TimeoutExpired:
        print("   ⏰ 命令超时 | Command timeout")
        return False, "", "Command timeout"
    except FileNotFoundError:
        print(f"   ⚠️  命令不可用 | Command not available: {command[0]}")
        return False, "", f"Command not found: {command[0]}"
    except Exception as e:
        print(f"   💥 执行错误 | Execution error: {e}")
        return False, "", str(e)


def check_file_exists(file_path: str) -> bool:
    """检查文件是否存在 | Check if file exists"""
    exists = Path(file_path).exists()
    if not exists:
        print(f"   ⚠️  文件不存在 | File not found: {file_path}")
    return exists


def run_mypy_checks() -> bool:
    """运行 MyPy 类型检查 | Run MyPy type checking"""
    print("\n" + "=" * 60)
    print("🐍 MyPy 类型检查 | MyPy Type Checking")
    print("=" * 60)
    
    # 检查配置文件 | Check config file
    config_file = "mypy.ini"
    if not check_file_exists(config_file):
        print(f"   使用默认配置 | Using default configuration")
        config_args = []
    else:
        config_args = ["--config-file", config_file]
    
    # 要检查的文件列表 | Files to check
    files_to_check = [
        "config.py",
        "main.py", 
        "static_type_examples.py",
        "collaborative_dev_example.py",
        "tests/test_static_types.py"
    ]
    
    # 过滤存在的文件 | Filter existing files
    existing_files = [f for f in files_to_check if check_file_exists(f)]
    
    if not existing_files:
        print("   ⚠️  没有找到要检查的文件 | No files found to check")
        return False
    
    all_success = True
    
    for file_path in existing_files:
        command = ["python", "-m", "mypy"] + config_args + [file_path]
        success, _, _ = run_command(command, f"检查文件 | Checking file: {file_path}")
        all_success = all_success and success
        print()
    
    return all_success


def run_pyright_checks() -> bool:
    """运行 Pyright 类型检查 | Run Pyright type checking"""
    print("\n" + "=" * 60)
    print("🔍 Pyright 类型检查 | Pyright Type Checking")
    print("=" * 60)
    
    # 检查配置文件 | Check config file
    config_file = "pyrightconfig.json"
    if not check_file_exists(config_file):
        print("   使用默认配置 | Using default configuration")
    
    # 运行 Pyright | Run Pyright
    command = ["pyright", "."]
    success, _, _ = run_command(command, "运行 Pyright 检查 | Running Pyright check")
    
    return success


def run_flake8_checks() -> bool:
    """运行 Flake8 代码风格检查 | Run Flake8 code style checking"""
    print("\n" + "=" * 60)
    print("🎨 Flake8 代码风格检查 | Flake8 Code Style Checking")
    print("=" * 60)
    
    # 要检查的文件和目录 | Files and directories to check
    targets = [
        "config.py",
        "main.py", 
        "static_type_examples.py",
        "collaborative_dev_example.py",
        "tests/",
        "gpio/",
        "uart/",
        "pwm/",
        "i2c/",
        "spi/"
    ]
    
    # 过滤存在的目标 | Filter existing targets
    existing_targets = [t for t in targets if Path(t).exists()]
    
    if not existing_targets:
        print("   ⚠️  没有找到要检查的目标 | No targets found to check")
        return False
    
    command = ["python", "-m", "flake8"] + existing_targets + [
        "--max-line-length=100",
        "--ignore=E501,W503,E203"  # 忽略一些常见的风格问题
    ]
    
    success, _, _ = run_command(command, "运行 Flake8 检查 | Running Flake8 check")
    return success


def run_tests() -> bool:
    """运行单元测试 | Run unit tests"""
    print("\n" + "=" * 60)
    print("🧪 单元测试 | Unit Tests")
    print("=" * 60)
    
    test_files = [
        "tests/test_static_types.py"
    ]
    
    # 过滤存在的测试文件 | Filter existing test files
    existing_tests = [t for t in test_files if check_file_exists(t)]
    
    if not existing_tests:
        print("   ⚠️  没有找到测试文件 | No test files found")
        return False
    
    all_success = True
    
    for test_file in existing_tests:
        command = ["python", "-m", "pytest", test_file, "-v"]
        success, _, _ = run_command(command, f"运行测试 | Running test: {test_file}")
        all_success = all_success and success
        print()
    
    return all_success


def generate_report(results: List[Tuple[str, bool]]) -> bool:
    """生成检查报告 | Generate checking report"""
    print("\n" + "=" * 60)
    print("📊 检查报告 | Checking Report")
    print("=" * 60)
    
    total_checks = len(results)
    passed_checks = sum(1 for _, success in results if success)
    failed_checks = total_checks - passed_checks
    
    print(f"总检查项 | Total checks: {total_checks}")
    print(f"通过 | Passed: {passed_checks}")
    print(f"失败 | Failed: {failed_checks}")
    print(f"成功率 | Success rate: {(passed_checks/total_checks*100):.1f}%")
    
    print("\n详细结果 | Detailed results:")
    for check_name, success in results:
        status_icon = "✅" if success else "❌"
        status_text = "通过" if success else "失败"
        print(f"  {status_icon} {check_name}: {status_text}")
    
    print("\n" + "=" * 60)
    
    if failed_checks == 0:
        print("🎉 所有检查通过！| All checks passed!")
        return True
    else:
        print("💥 部分检查失败！| Some checks failed!")
        return False


def main() -> None:
    """主函数 | Main function"""
    print("MicroPython 协作开发指南 - 类型检查运行器")
    print("MicroPython Collaborative Development Guide - Type Checking Runner")
    print("=" * 70)
    
    # 检查当前工作目录 | Check current working directory
    current_dir = Path.cwd()
    print(f"当前目录 | Current directory: {current_dir}")
    
    # 运行所有检查 | Run all checks
    results: List[Tuple[str, bool]] = []
    
    # MyPy 检查 | MyPy checks
    mypy_success = run_mypy_checks()
    results.append(("MyPy 类型检查 | MyPy Type Checking", mypy_success))
    
    # Pyright 检查 | Pyright checks
    pyright_success = run_pyright_checks()
    results.append(("Pyright 类型检查 | Pyright Type Checking", pyright_success))
    
    # Flake8 检查 | Flake8 checks
    flake8_success = run_flake8_checks()
    results.append(("Flake8 代码风格检查 | Flake8 Code Style", flake8_success))
    
    # 单元测试 | Unit tests
    test_success = run_tests()
    results.append(("单元测试 | Unit Tests", test_success))
    
    # 生成报告 | Generate report
    overall_success = generate_report(results)
    
    # 设置退出码 | Set exit code
    sys.exit(0 if overall_success else 1)


if __name__ == "__main__":
    main()
